package com.zwy.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.args.BitCountOption;
import redis.clients.jedis.args.BitOP;

@Component
public class RedisBitMapUtil {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private JedisPool jedisPool;

    /**
     * 设置bitmap
     * @param dbIndex
     * @param key
     * @param offset 大于0 小于2^32 而Integer最大 2^31 - 1，为了避免超出最好在int范围20多亿的数据
     * @param flag
     */
    public void setBit(Integer dbIndex, String key, Integer offset, boolean flag){
        try(Jedis jedis = jedisPool.getResource()) {
            jedis.select(dbIndex);
            jedis.setbit(key,offset, flag);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw e;
        }
    }

    /**
     * 获取
     * @param dbIndex
     * @param key
     * @param offset
     * @return
     */
    public boolean getBit(Integer dbIndex, String key, Integer offset){
        try(Jedis jedis = jedisPool.getResource()) {
            jedis.select(dbIndex);
            return jedis.getbit(key,offset);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw e;
        }
    }

    /**
     * 返回Bit数量
     * @param dbIndex
     * @param key
     * @param start
     * @param offset
     * @return
     */
    public long bitcount(Integer dbIndex, String key, Long start, Long offset){
        try(Jedis jedis = jedisPool.getResource()) {
            jedis.select(dbIndex);
            return jedis.bitcount(key, start, offset);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw e;
        }
    }

    /**
     * 将多个Bit合并
     * @param dbIndex
     * @param destKey
     * @param op operation 可以是 AND 、 OR 、 NOT 、 XOR 这四种操作中的任意一种：
     * @param srcKeys
     * @return
     */
    public long bitop(Integer dbIndex, String destKey, BitOP op, String... srcKeys){
        try(Jedis jedis = jedisPool.getResource()) {
            jedis.select(dbIndex);
            return jedis.bitop(op, destKey, srcKeys);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw e;
        }
    }
}
